package com.xbongbong.workflow.service.strategy.data.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.TaskTypeEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.util.FormDataUtil;
import com.xbongbong.pro.domain.entity.FormConfigEntity;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.workflow.enums.WorkflowOperateEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.BomProductEntity;
import com.xbongbong.saas.domain.entity.BomUserEntity;
import com.xbongbong.saas.domain.entity.ext.BomBillEntityExt;
import com.xbongbong.saas.enums.FormConfigEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.BomBillEnum;
import com.xbongbong.saas.model.BomBillModel;
import com.xbongbong.saas.model.BomProductModel;
import com.xbongbong.saas.model.BomUserModel;
import com.xbongbong.saas.model.ContractProductModel;
import com.xbongbong.saas.model.FormConfigModel;
import com.xbongbong.saas.model.PaasFormSubDataModel;
import com.xbongbong.workflow.domain.entity.WorkflowBackupDataEntity;
import com.xbongbong.workflow.model.WorkflowBackupDataModel;
import com.xbongbong.workflow.pojo.Data;
import com.xbongbong.workflow.pojo.WorkflowTransferPOJO;
import com.xbongbong.workflow.service.strategy.data.AbstractWorkflowDataStrategy;
import com.xbongbong.workflow.service.strategy.data.WorkflowDataProcessStrategy;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 *
 * @author 魏荣杰
 *
 */
@Service
public class WorkflowBomBillStrategy extends AbstractWorkflowDataStrategy implements WorkflowDataProcessStrategy {

    private static final Logger log = LoggerFactory.getLogger(WorkflowBomBillStrategy.class);

    @Resource
    private WorkflowBackupDataModel workflowBackupDataModel;
    @Resource
    private BomBillModel bomBillModel;
    @Resource
    private BomProductModel bomProductModel;
    @Resource
    private BomUserModel bomUserModel;
    @Resource
    private FormConfigModel formConfigModel;
    @Resource
    protected ContractProductModel contractProductModel;
    @Resource
    private PaasFormSubDataModel paasFormSubDataModel;


    @Override
    public List<Integer> type() {
        return Collections.singletonList(XbbRefTypeEnum.BOM_BILL.getCode());
    }

    @Override
    public void save(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        // 文件柜保存
        saveDataCabinetFile(workflowTransferPOJO);
        addLinkDataDynamic(workflowTransferPOJO);
        // api
        apiHook(workflowTransferPOJO);
        // log
        afterSaveLog(workflowTransferPOJO);
    }

    @Override
    public void update(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        // 文件柜保存
        saveDataCabinetFile(workflowTransferPOJO);
        // api
        apiHook(workflowTransferPOJO);
        // log
        afterUpdateLog(workflowTransferPOJO);
    }

    @Override
    public void updateBack(Long taskId, WorkflowTransferPOJO workflowTransferPOJO) throws XbbException {
        try {
            String corpid = workflowTransferPOJO.getCorpid();
            Long backupDataId = workflowTransferPOJO.getBackupDataId();
            Long dataId = workflowTransferPOJO.getData().getId();
            WorkflowBackupDataEntity workflowBackupDataEntity = workflowBackupDataModel.getByKey(backupDataId, corpid);
            if (Objects.nonNull(workflowBackupDataEntity)) {
                JSONObject data = workflowBackupDataEntity.getData();

                replenishAttrForBackupData(workflowTransferPOJO.getData().getData(), data);

                BomBillEntityExt bomBillEntityExt = new BomBillEntityExt();
                bomBillEntityExt.setId(dataId);
                bomBillEntityExt.setCorpid(corpid);
                bomBillEntityExt.setData(data);
                bomBillEntityExt.setSerialNo(data.getString(FieldTypeEnum.SERIALNO.getAlias()));
                // 获取负责人
                bomBillEntityExt.setOwnerId(getOwnerId(data));
                bomBillEntityExt.setDepartmentId(data.getLong(FieldTypeEnum.DEPARTMENTID.getAlias()));
                List<BomProductEntity> list = JSON.parseArray(data.getString(StringConstant.PRODUCT), BomProductEntity.class);
                List<BomUserEntity> bomUserList = JSON.parseArray(data.getString(StringConstant.USER_TEAM), BomUserEntity.class);

                FormDataUtil.removeSystemData(data);
                data.remove(StringConstant.USER_TEAM);
                data.remove(StringConstant.PRODUCT);
                if (Objects.equals(workflowTransferPOJO.getOperate(), WorkflowOperateEnum.UPDATE.getType())) {
                    bomBillEntityExt.setFlowStatus(FlowStatusEnum.PASS.getType());
                }
                bomBillModel.update(bomBillEntityExt);
                // 回退被删掉的子表单
                updateBackSubForm(bomBillEntityExt, corpid, IndexTypeEnum.IDX_SAAS_BOM_SUB);
                //回退被删掉的富文本
                updateBackRichText(taskId, workflowTransferPOJO);
                saveUserTeam(bomUserList, corpid, bomBillEntityExt.getId());
                saveProduct(list, corpid, bomBillEntityExt.getId(), data);
            }
        } catch (Exception e) {
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowBomBillStrategy.updateBack error ", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    @Override
    public void approvalFailed(Long taskId, WorkflowTransferPOJO workflowTransferPOJO, Integer taskType) throws XbbException {
        try {
            String corpid = workflowTransferPOJO.getCorpid();
            Data workflowData = workflowTransferPOJO.getData();
            Long dataId = workflowData.getId();
            Long formId = workflowData.getFormId();
            Integer businessType = workflowData.getBusinessType();
            Integer saasMark = workflowData.getSaasMark();
            BomBillEntityExt bomBillEntityExt = new BomBillEntityExt();
            bomBillEntityExt.setId(dataId);
            if (Objects.equals(TaskTypeEnum.REVOKE.getType(), taskType)) {
                bomBillEntityExt.setFlowStatus(FlowStatusEnum.REVOKE.getType());
            } else {
                bomBillEntityExt.setFlowStatus(FlowStatusEnum.REJECT.getType());
            }
            bomBillEntityExt.setCorpid(corpid);
            bomBillEntityExt.setUpdateTime(DateTimeUtil.getInt());
            bomBillModel.update(bomBillEntityExt);
            // 子表单
            DelEnum del = DelEnum.APPROVE_FAILED;

            paasFormSubDataModel.deleteBatchByDataId(Collections.singletonList(dataId), corpid, IndexTypeEnum.IDX_SAAS_BOM_SUB, del);

            //富文本
            deleteFormRichText(dataId, corpid, formId, businessType, saasMark, DelEnum.NORMAL);
            // 关联产品
            List<BomProductEntity> productList = bomProductModel.getProductsByBomId(dataId, corpid, null);
            if (CollectionsUtil.isNotEmpty(productList)) {
                List<Long> idIn = new ArrayList<>();
                productList.forEach(item->idIn.add(item.getId()));
                bomProductModel.deleteBatch(idIn, corpid, del.getDel());
            }
            List<BomUserEntity> bomUserList = bomUserModel.getBomUserListByBomId(corpid, dataId);
            if (CollectionsUtil.isNotEmpty(bomUserList)) {
                bomUserModel.deleteBatchUser(bomUserList, corpid, DelEnum.APPROVE_FAILED.getDel());
            }
        } catch (Exception e) {
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowBomBillStrategy.approvalFailed error ", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    private void saveProduct(List<BomProductEntity> list, String corpid, Long dataId, JSONObject data) throws XbbException {
        try {
            List<BomProductEntity> productList = bomProductModel.getProductsByBomId(dataId, corpid, null);


            List<Long> deleteProductId = new ArrayList<>();
            // 遍历备份表中的产品
            List<Long> backupProductId = new ArrayList<>();
            list.forEach(item->backupProductId.add(item.getId()));

            productList.forEach(item->{
                if (!backupProductId.contains(item.getId())) {
                    deleteProductId.add(item.getId());
                }
            });

            if (CollectionsUtil.isNotEmpty(deleteProductId)) {
                bomProductModel.deleteByIdIn(deleteProductId, corpid);
            }
            if (CollectionsUtil.isNotEmpty(list)) {
                bomProductModel.updateBatch(list, corpid);
            }

            // 保存bom单产品时，会去更新合同产品的“代表该合同产品是显示在待生产列表还是待采购列表”的属性 此处是否需要回滚
            // 状态
            String status = BomBillEnum.STATUS.getAttr();
            if (data.containsKey(status)){

                // 获取[新建合同订单缺货时自动更新]表单配置
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(ParameterConstant.CORPID, corpid);
                param.put("config", FormConfigEnum.PRODUCTION_ORDER_AUTO_UPDATE_NEW_CONTRACT.getConfig());
                List<FormConfigEntity> formConfigList = formConfigModel.findEntitys(param);
                if(CollectionUtils.isNotEmpty(formConfigList)){
                    // 代表该合同产品是显示在待生产列表还是待采购列表，1：待生产列表；0：待采购列表，默认0
                    // bom禁用是状态标记为0
                    int isProduce = "0".equals(data.get(status)) ? 0 : 1;
                    // 同一个公司同一个配置选择应当只有一个
                    FormConfigEntity formConfigEntity = formConfigList.get(0);
                    // 只有勾选了才进这段才会进生产单,没勾选不管bom启用还是禁用都去待采购列表
                    if(StringUtils.equals(formConfigEntity.getConfigValue(), BasicConstant.ZERO.toString())){
                        isProduce = 0;
                    }
                    // 更新合同产品数据
                    List<Long> productIdList = new ArrayList<>();
                    productList.forEach(item->{
                        if (Objects.equals(item.getType(), 1)) {
                            productIdList.add(item.getProductId());
                        }
                    });
                    contractProductModel.updateIsProduceByProductId(isProduce, corpid, productIdList);
                }
            }
        } catch (Exception e) {
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowBomBillStrategy.saveProduct error ", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    private void saveUserTeam(List<BomUserEntity> list, String corpid, Long dataId) throws XbbException {

        try {
            List<BomUserEntity> bomUserList = bomUserModel.getBomUserListByBomId(corpid, dataId);
            List<Long> idList = new ArrayList<>();
            list.forEach(item->idList.add(item.getId()));


            bomUserList.removeIf(item->idList.contains(item.getId()));
            if (CollectionsUtil.isNotEmpty(bomUserList)) {
                bomUserModel.deleteBatchUser(bomUserList, corpid, DelEnum.DELETE.getDel());
            }
            if (CollectionsUtil.isNotEmpty(list)) {
                bomUserModel.updateBatch(list, corpid);
            }


        } catch (Exception e) {
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowBomBillStrategy.saveUserTeam error ", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

}
